const { sequelize } = require('../config/database');
const logger = require('../config/logger');

// 导入所有模型
const User = require('./User');
const Course = require('./Course');
const Exam = require('./Exam');

// 定义模型关联关系
const defineAssociations = () => {
  try {
    // 用户和课程的关联
    // 一个用户可以创建多个课程（教师）
    User.hasMany(Course, {
      foreignKey: 'teacherId',
      as: 'teachingCourses',
      onDelete: 'RESTRICT',
      onUpdate: 'CASCADE'
    });
    
    Course.belongsTo(User, {
      foreignKey: 'teacherId',
      as: 'teacher',
      onDelete: 'RESTRICT',
      onUpdate: 'CASCADE'
    });
    
    // 用户和考试的关联
    // 一个用户可以创建多个考试（教师）
    User.hasMany(Exam, {
      foreignKey: 'teacherId',
      as: 'createdExams',
      onDelete: 'RESTRICT',
      onUpdate: 'CASCADE'
    });
    
    Exam.belongsTo(User, {
      foreignKey: 'teacherId',
      as: 'teacher',
      onDelete: 'RESTRICT',
      onUpdate: 'CASCADE'
    });
    
    // 课程和考试的关联
    // 一个课程可以有多个考试
    Course.hasMany(Exam, {
      foreignKey: 'courseId',
      as: 'exams',
      onDelete: 'CASCADE',
      onUpdate: 'CASCADE'
    });
    
    Exam.belongsTo(Course, {
      foreignKey: 'courseId',
      as: 'course',
      onDelete: 'CASCADE',
      onUpdate: 'CASCADE'
    });
    
    logger.info('模型关联关系定义完成');
  } catch (error) {
    logger.error('定义模型关联关系失败:', error);
    throw error;
  }
};

// 同步数据库
const syncDatabase = async (options = {}) => {
  try {
    const {
      force = false,
      alter = false,
      logging = true
    } = options;
    
    logger.info('开始同步数据库...');
    
    // 定义关联关系
    defineAssociations();
    
    // 同步所有模型
    await sequelize.sync({
      force,
      alter,
      logging: logging ? (sql) => logger.sql('Sequelize', sql) : false
    });
    
    logger.info('数据库同步完成');
  } catch (error) {
    logger.error('数据库同步失败:', error);
    throw error;
  }
};

// 创建初始数据
const createInitialData = async () => {
  try {
    logger.info('开始创建初始数据...');
    
    // 检查是否已有超级管理员
    const superAdmin = await User.findOne({
      where: { role: 'super_admin' }
    });
    
    if (!superAdmin) {
      // 创建默认超级管理员
      const defaultAdmin = await User.create({
        username: 'admin',
        email: 'admin@example.com',
        password: 'admin123456', // 生产环境中应该使用更安全的密码
        realName: '系统管理员',
        role: 'super_admin',
        status: 'active',
        emailVerified: true,
        permissions: ['*']
      });
      
      logger.info('默认超级管理员创建成功:', {
        id: defaultAdmin.id,
        username: defaultAdmin.username,
        email: defaultAdmin.email
      });
    }
    
    // 可以在这里添加其他初始数据的创建逻辑
    // 比如默认课程分类、系统配置等
    
    logger.info('初始数据创建完成');
  } catch (error) {
    logger.error('创建初始数据失败:', error);
    throw error;
  }
};

// 验证数据库连接和模型
const validateModels = async () => {
  try {
    logger.info('开始验证数据库模型...');
    
    // 测试数据库连接
    await sequelize.authenticate();
    logger.info('数据库连接验证成功');
    
    // 验证模型定义
    const models = [User, Course, Exam];
    for (const model of models) {
      const tableName = model.getTableName();
      logger.info(`模型 ${model.name} -> 表 ${tableName} 验证成功`);
    }
    
    logger.info('数据库模型验证完成');
  } catch (error) {
    logger.error('数据库模型验证失败:', error);
    throw error;
  }
};

// 获取模型统计信息
const getModelStats = async () => {
  try {
    const stats = {};
    
    // 用户统计
    stats.users = {
      total: await User.count(),
      active: await User.count({ where: { status: 'active' } }),
      students: await User.count({ where: { role: 'student' } }),
      teachers: await User.count({ where: { role: 'teacher' } }),
      admins: await User.count({ where: { role: 'admin' } })
    };
    
    // 课程统计
    stats.courses = {
      total: await Course.count(),
      published: await Course.count({ where: { status: 'published' } }),
      draft: await Course.count({ where: { status: 'draft' } }),
      free: await Course.count({ where: { isFree: true } })
    };
    
    // 考试统计
    stats.exams = {
      total: await Exam.count(),
      published: await Exam.count({ where: { status: 'published' } }),
      draft: await Exam.count({ where: { status: 'draft' } }),
      public: await Exam.count({ where: { isPublic: true } })
    };
    
    return stats;
  } catch (error) {
    logger.error('获取模型统计信息失败:', error);
    throw error;
  }
};

// 清理过期数据
const cleanupExpiredData = async () => {
  try {
    logger.info('开始清理过期数据...');
    
    const now = new Date();
    
    // 清理过期的邮箱验证令牌
    const expiredEmailTokens = await User.update(
      {
        emailVerificationToken: null,
        emailVerificationExpires: null
      },
      {
        where: {
          emailVerificationExpires: {
            [sequelize.Sequelize.Op.lt]: now
          }
        }
      }
    );
    
    // 清理过期的密码重置令牌
    const expiredPasswordTokens = await User.update(
      {
        passwordResetToken: null,
        passwordResetExpires: null
      },
      {
        where: {
          passwordResetExpires: {
            [sequelize.Sequelize.Op.lt]: now
          }
        }
      }
    );
    
    // 解锁过期的账户锁定
    const unlockedAccounts = await User.update(
      {
        loginAttempts: 0,
        lockUntil: null
      },
      {
        where: {
          lockUntil: {
            [sequelize.Sequelize.Op.lt]: now
          }
        }
      }
    );
    
    logger.info('过期数据清理完成', {
      expiredEmailTokens: expiredEmailTokens[0],
      expiredPasswordTokens: expiredPasswordTokens[0],
      unlockedAccounts: unlockedAccounts[0]
    });
  } catch (error) {
    logger.error('清理过期数据失败:', error);
    throw error;
  }
};

// 备份数据库（仅开发环境）
const backupDatabase = async () => {
  if (process.env.NODE_ENV === 'production') {
    logger.warn('生产环境不支持通过此方法备份数据库');
    return;
  }
  
  try {
    logger.info('开始备份数据库...');
    
    // 这里可以实现数据库备份逻辑
    // 比如导出SQL文件或创建数据快照
    
    logger.info('数据库备份完成');
  } catch (error) {
    logger.error('数据库备份失败:', error);
    throw error;
  }
};

// 导出模型和工具函数
module.exports = {
  // 数据库实例
  sequelize,
  
  // 模型
  User,
  Course,
  Exam,
  
  // 工具函数
  defineAssociations,
  syncDatabase,
  createInitialData,
  validateModels,
  getModelStats,
  cleanupExpiredData,
  backupDatabase,
  
  // 初始化函数
  async initialize(options = {}) {
    try {
      logger.info('开始初始化数据库模型...');
      
      // 验证模型
      await validateModels();
      
      // 同步数据库
      await syncDatabase(options.sync || {});
      
      // 创建初始数据
      if (options.createInitialData !== false) {
        await createInitialData();
      }
      
      // 清理过期数据
      if (options.cleanup !== false) {
        await cleanupExpiredData();
      }
      
      logger.info('数据库模型初始化完成');
    } catch (error) {
      logger.error('数据库模型初始化失败:', error);
      throw error;
    }
  },
  
  // 关闭数据库连接
  async close() {
    try {
      await sequelize.close();
      logger.info('数据库连接已关闭');
    } catch (error) {
      logger.error('关闭数据库连接失败:', error);
      throw error;
    }
  }
};